package com.king.platform.config;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Response;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
@EnableOpenApi
@EnableKnife4j
public class SwaggerConfig
{
  @Bean
  public Docket createRestApi() {
    List<Response> responseMessageList = new ArrayList();
    responseMessageList.add((new ResponseBuilder()).code("200").description("成功").build());
    responseMessageList.add((new ResponseBuilder()).code("400").description("请求返回错误").build());
    responseMessageList.add((new ResponseBuilder()).code("404").description("找不到资源").build());
    responseMessageList.add((new ResponseBuilder()).code("409").description("业务逻辑异常").build());
    responseMessageList.add((new ResponseBuilder()).code("422").description("参数校验异常").build());
    responseMessageList.add((new ResponseBuilder()).code("500").description("服务器内部错误").build());
    responseMessageList.add((new ResponseBuilder()).code("503").description("Hystrix异常").build());
    return (new Docket(DocumentationType.OAS_30)).
        apiInfo(this.apiInfo()).select().
        apis(RequestHandlerSelectors.basePackage("com.king")).
        paths(PathSelectors.any()).build().
        globalResponses(HttpMethod.GET, responseMessageList).
        globalResponses(HttpMethod.POST, responseMessageList).
        globalResponses(HttpMethod.DELETE, responseMessageList).
        globalResponses(HttpMethod.PUT, responseMessageList);
  }

  private ApiInfo apiInfo() {
    return (new ApiInfoBuilder()).title("Swagger 接口服务API文档")
        .description("会员管理系统")
        .version("1.0")
        .license("version1.0.1")
        .contact(new Contact("king", "11", "king@hotmail.com"))
        .build();
  }

  @Bean
  public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
    return new BeanPostProcessor() {

      @Override
      public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
          customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
        }
        return bean;
      }

      private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
        List<T> copy = mappings.stream()
            .filter(mapping -> mapping.getPatternParser() == null)
            .collect(Collectors.toList());
        mappings.clear();
        mappings.addAll(copy);
      }

      @SuppressWarnings("unchecked")
      private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
        try {
          Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
          field.setAccessible(true);

          return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
        } catch (IllegalArgumentException | IllegalAccessException e) {
          throw new IllegalStateException(e);
        }
      }
    };
  }



}
